<?php
namespace app\common\lib;

use think\facade\Log;

class CryptoJsAes
{
    /**
     * aes 加密
     * @author 贺强
     * @time   2022/5/5 10:24
     * @param string $value      要加密的数据
     * @param string $passphrase 加密密码
     * @return array|false       返回加密后的数据
     */
    public static function encrypt($value, string $passphrase)
    {
        try {
            $salt = openssl_random_pseudo_bytes(8);
            $salted = '';
            $dx = '';
            while (strlen($salted) < 48) {
                $dx = md5($dx . $passphrase . $salt, true);
                $salted .= $dx;
            }
            $key = substr($salted, 0, 32);
            $iv = substr($salted, 32, 16);
            $encrypted_data = openssl_encrypt(json_encode($value), 'aes-256-cbc', $key, true, $iv);
            $data = ["ct" => base64_encode($encrypted_data), "iv" => bin2hex($iv), "s" => bin2hex($salt)];
            return $data;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
    }

    /**
     * aes 解密
     * @author 贺强
     * @time   2022/5/5 10:27
     * @param string $data       要解密的数据
     * @param string $passphrase 解密密码
     * @return false|array       返回解密后的数据
     */
    public static function decrypt($data, string $passphrase)
    {
        try {
            if (is_string($data)) {
                $data = json_decode($data, true);
            }
            $salt = hex2bin($data["s"]);
            $iv = hex2bin($data["iv"]);
            $ct = base64_decode($data["ct"]);
            $concatedPassphrase = $passphrase . $salt;
            $md5 = [];
            $md5[0] = md5($concatedPassphrase, true);
            $result = $md5[0];
            for ($i = 1; $i < 3; $i++) {
                $md5[$i] = md5($md5[$i - 1] . $concatedPassphrase, true);
                $result .= $md5[$i];
            }
            $key = substr($result, 0, 32);
            $data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
            return json_decode($data, true);
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
    }

    /**
     * 使用指定的盐和向量进行 aes 加密
     * @author 贺强
     * @time   2023/5/17 15:36
     * @param string $value      要加密的字符串
     * @param string $passphrase 密钥
     * @param string $iv         向量
     * @return string|false
     */
    public static function encryptT($value = '', string $passphrase = '', $iv = '')
    {
        try {
            $encrypted_data = openssl_encrypt($value, 'aes-128-cbc', $passphrase, true, $iv);
            $data = base64_encode($encrypted_data);
            return $data;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
    }

    /**
     * 使用指定的盐和向量进行 aes 解密
     * @author 贺强
     * @time   2023/5/17 15:54
     * @param string $data       要解密的数据
     * @param string $passphrase 密钥
     * @param string $iv         向量
     * @return mixed
     */
    public static function decryptT($data = '', string $passphrase = '', $iv = '')
    {
        try {
            $data = base64_decode($data);
            $res = openssl_decrypt($data, 'aes-128-cbc', $passphrase, true, $iv);
            return $res;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return false;
        }
    }
}
